import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import './rodal.css';
import Rodal from './rodal';
import './mModal.css';
import { Spin } from 'antd';

class Modal extends Component {
    static propTypes = {
        children: PropTypes.node,
        onClose: PropTypes.func.isRequired,
        duration: PropTypes.number,
        zIndex: PropTypes.number,
        showTopClose: PropTypes.bool,
        visible: PropTypes.bool
    };
    static defaultProps = {
        showTopClose: true
    };
    state = {
        showCloseBtn: false
    };
    componentDidMount() {
        this.createShowCloseBtnTimer();
        this.onClose = () => this.props.onClose();
    }
    createShowCloseBtnTimer = () => {
        if (this.props.showTopClose) {
            const duration = this.props.duration ? this.props.duration + 200 : 300 + 200;
            this.showCloseBtnTimer = setTimeout(() => {
                this.setState({ showCloseBtn: true });
            }, duration);
        }
    };
    componentWillReceiveProps(nextProps) {
        if (!nextProps.visible) {
            this.setState({ showCloseBtn: false });
        } else {
            this.createShowCloseBtnTimer();
        }
    }
    componentWillUnmount() {
        clearTimeout(this.showCloseBtnTimer);
    }
    render() {
        return (
            <Rodal
                closeMaskOnClick={true}
                closeOnEsc={false}
                showCloseButton={false}
                showMask={false}
                {...this.props}>
                <div className="mModal-dialog-wrap">
                    {this.state.showCloseBtn && <a className="mModal-dialog-close" href="javascript:void(0);" onClick={this.onClose}/>}
                    {this.props.children}
                </div>
            </Rodal>
        );
    }
}

class MModal extends Component {
    static propTypes = {
        visible: PropTypes.bool,
        children: PropTypes.node,
        onClose: PropTypes.func.isRequired,
        duration: PropTypes.number
    };
    state = {
        showCloseBtn: false
    };
    constructor(props) {
        super(props);
        if (props.visible) {
            this.container = document.createElement('div');
            document.body.appendChild(this.container);
        }
    }
    static confirm = options => {
        options = options ? options : {};

        const {
            title = "确认？",
            titleStyle,
            content = '',
            contentStyle,
            okText = '确定',
            cancelText = '取消',
            onOk = () => {},
            onCancel = () => {},
            onClose = () => {},
            width = 480,
            height = 350,
            zIndex = 100,
            showBtn = true,
            okStyle,
            cancelStyle,
            okClassName = 'default-btn-ok',
            cancelClassName = 'default-btn-cancel',
            showTopClose = true,
            closeMaskOnClick = false
        } = options;
        const closeConfirm = () => {
            ReactDOM.unmountComponentAtNode(container);
            document.body.removeChild(container);
        };
        let container = document.createElement('div');
        document.body.appendChild(container);

        return new Promise((resolve, reject) => {
            class ConfirmModal extends Component {
                constructor() {
                    super();
                    this.closed = false;
                    resolve(this.closeModal);
                }
                static propTypes = {
                    closeModal: PropTypes.func.isRequired
                };
                state = {
                    visible: true,
                    spinning: false
                };
                closeModal = () => {
                    if (this.closed) return;
                    clearTimeout(this.timer);
                    this.closed = true;
                    onClose();
                    this.setState({ visible: false });
                    this.timer = setTimeout(() => { this.props.closeModal() }, 500);
                };
                componentWillUnmount() {
                    clearTimeout(this.timer);
                    if (this.closed) return;
                    this.props.closeModal();
                }
                cancelClick = async () => {
                    this.setState({ spinning: true });
                    if (typeof onCancel === 'function') await onCancel();
                    this.closeModal();
                };
                okClick = async () => {
                    this.setState({ spinning: true });
                    if (typeof onOk === 'function') await onOk();
                    this.closeModal();
                };
                render() {
                    let operBtns;
                    operBtns =
                        <div className="default-btn-wrap">
                            <a className={okClassName} style={okStyle} href="javascript:void(0);" onClick={this.okClick}>{okText}</a>
                            <a className={cancelClassName} style={cancelStyle} href="javascript:void(0);" onClick={this.cancelClick}>{cancelText}</a>
                        </div>;
                    let _content = typeof content === 'function' ?
                        content(this.closeModal) //传回关闭方法
                        : content;
                    return (
                        <Modal visible={this.state.visible} onClose={this.closeModal} width={width}
                            height={height} zIndex={zIndex} showTopClose={showTopClose} showMask closeMaskOnClick={closeMaskOnClick}>
                            <Spin tip="loading" spinning={this.state.spinning} delay={150}>
                                <div className="mModal-confirm-dialog">
                                    <div className="mc-modal-title" style={titleStyle}>
                                        {title}
                                    </div>
                                    <div className="mc-modal-content" style={contentStyle}>
                                        {_content}
                                    </div>
                                    {showBtn &&
                                    <div className="mc-modal-btns">
                                        {operBtns}
                                    </div>}
                                </div>
                            </Spin>
                        </Modal>
                    );
                }
            }

            ReactDOM.render(
                <ConfirmModal closeModal={closeConfirm} />,
                container
            );
        });
    };
    componentWillReceiveProps(nextProps) {
        if (nextProps.visible && !this.container) {
            this.container = document.createElement('div');
            document.body.appendChild(this.container);
        }
    }
    componentWillUnmount() {
        if (this.container) document.body.removeChild(this.container);
    }
    render() {
        if (this.container) {
            return ReactDOM.createPortal(
                <Modal {...this.props}/>,
                this.container,
            );
        } else {
            return null;
        }
    }
}

MModal.success = async options => {
    const {
        title = 'success',
        content = '',
        zIndex = 101,
        duration = false //单位秒
    } = options;
    let timer;
    const _hide = await MModal.confirm({
        title: title,
        titleStyle: { fontSize: 16 },
        width: 380,
        height: 170,
        zIndex: zIndex,
        showTopClose: false,
        showBtn: false,
        closeMaskOnClick: true,
        onClose: () => clearTimeout(timer),
        content: hide => {
            const okClick = () => {
                clearTimeout(timer);  //关闭定时器
                hide();
            };
            return <div className="mModal-confirm-success"><div className="success-content">{content}</div>
                <a className="mModal-confirm-success-btn" href="javascript:void(0);" onClick={okClick}>确定</a></div>
        }
    });
    if (duration !== false) {
        timer = setTimeout(_hide, duration * 1000);
    }
    return _hide;
};

export default MModal;